package io.zhengsh.br1.controller;

import io.lettuce.core.RedisClient;
import io.zhengsh.br1.util.RedisUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
public class GoodsController {

    private Logger logger = LoggerFactory.getLogger(GoodsController.class);

    private final String REDIS_LOCK = "good_lock";
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value("${server.port}")
    private Integer serverPort;
    @Autowired
    private Redisson redisson;

    @GetMapping("/buyGoods")
    public String buyGoods() {
        RLock rLock = redisson.getLock(REDIS_LOCK);
        rLock.lock();
        try {
            String result = stringRedisTemplate.opsForValue().get("goods:001");
            int goodsNumber = result == null ? 0 : Integer.valueOf(result);
            if (goodsNumber > 0) {
                int realNumber = goodsNumber - 1;
                stringRedisTemplate.opsForValue().set("goods:001", String.valueOf(realNumber));
                logger.info("成功买到商品， 库存还剩下：{} 件｜服务提供者 serverPort : {}", realNumber, serverPort);


                return "成功买到商品， 库存还剩下：" + realNumber + " 件｜服务提供者 serverPort : " + serverPort;
            }
            logger.info("商品已经售完/活动结束/调用超时, 欢迎下次光临, serverPort:{}", serverPort);
            return "商品已经售完/活动结束/调用超时, 欢迎下次光临, serverPort:" + serverPort;
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }


//    @GetMapping("/buyGoods")
//    public String buyGoods() {
//        String value = UUID.randomUUID().toString() + Thread.currentThread().getName();
//        try {
//            // 加锁
//            //Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(REDIS_LOCK, value);//NX
//            // 10s 过期
//            // stringRedisTemplate.expire(REDIS_LOCK, 10L, TimeUnit.SECONDS);
//            Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(REDIS_LOCK, value, 10L, TimeUnit.SECONDS);//NX
//            if (Boolean.FALSE.equals(flag)) {
//                logger.info("抢锁失败, serverPort:{}", serverPort);
//                return "抢锁失败";
//            }
//
//            String result = stringRedisTemplate.opsForValue().get("goods:001");
//            int goodsNumber = result == null ? 0 : Integer.valueOf(result);
//            if (goodsNumber > 0) {
//                int realNumber = goodsNumber - 1;
//                stringRedisTemplate.opsForValue().set("goods:001", String.valueOf(realNumber));
//                logger.info("成功买到商品， 库存还剩下：{} 件｜服务提供者 serverPort : {}", realNumber, serverPort);
//
//
//                return "成功买到商品， 库存还剩下：" + realNumber + " 件｜服务提供者 serverPort : " + serverPort;
//            }
//            logger.info("商品已经售完/活动结束/调用超时, 欢迎下次光临, serverPort:{}", serverPort);
//            return "商品已经售完/活动结束/调用超时, 欢迎下次光临, serverPort:" + serverPort;
//        } finally {
//            // 解锁
//            /*
//            if (Objects.equals(stringRedisTemplate.opsForValue().get(REDIS_LOCK), value)) {
//                stringRedisTemplate.delete(REDIS_LOCK);
//            }
//            */
//
//            /*
//            while (true) {
//                stringRedisTemplate.watch(REDIS_LOCK);
//                if (Objects.equals(stringRedisTemplate.opsForValue().get(REDIS_LOCK), value)) {
//                    stringRedisTemplate.setEnableTransactionSupport(true);
//                    stringRedisTemplate.multi();
//                    stringRedisTemplate.delete(REDIS_LOCK);
//                    List<Object> list = stringRedisTemplate.exec();
//                    if (CollectionUtils.isEmpty(list)) {
//                        continue;
//                    }
//                }
//                stringRedisTemplate.unwatch();
//                break;
//            }
//            */
//
//            String RELEASE_LOCK_LUA_SCRIPT = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n" +
//                    "    return redis.call(\"del\",KEYS[1])\n" +
//                    "else\n" +
//                    "    return 0\n" +
//                    "end";
//            DefaultRedisScript<Long> redisScript =
//                    new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
//            // 参数一：redisScript，参数二：key列表，参数三：arg（可多个）
//            Long result = stringRedisTemplate.execute(redisScript,
//                    Collections.singletonList(REDIS_LOCK), value);
//            if (Objects.equals(result, 1)) {
//                logger.info(" ========> del redis lock ok!");
//            } else {
//                logger.info(" ========> del redis lock err!");
//            }
//        }
//    }
}
